#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<signal.h>
#include<sys/time.h>
#include<fcntl.h>
#include<unistd.h> 
#include<pthread.h>
#include<semaphore.h>
#include<iostream>
#include<queue>

#define NUM 5
std::queue<int> que;
sem_t remain, product;

void err_threaed(int ret, char const *str){
    fprintf(stderr, "%s error: %s\n", strerror(ret));
    exit(1);
}

void* producer(void* arg){
    srand(time(NULL));
    int t;
    while(1){ 
        t = rand() % 1000 +1;
        sem_wait(&remain);
        que.push(t);
        printf("producter: %d\n", t);
        sem_post(&product); 
    } 
   
}

void* consumer(void* arg){
    srand(time(NULL));
    int t;     
    while(1){
        sem_wait(&product);
        t = que.front();
        que.pop();
        sem_post(&remain);
        printf("consumer: %d\n", t);
    }
}

int main(int argc, char* args[])
{
    int ret;

    //初始化sem信号量
    ret = sem_init(&remain, 0, NUM);
    if(ret)
        err_threaed(ret, "sem_init remain");
    ret = sem_init(&product, 0, 0);
    if(ret)
        err_threaed(ret, "sem_init remain");
    
    //创建线程
    pthread_t ptid, ctid;
    ret = pthread_create(&ptid, NULL, producer, NULL);
    if(ret)
        err_threaed(ret, "pthread_create producer");
    ret = pthread_create(&ctid, NULL, consumer, NULL);
    if(ret)
        err_threaed(ret, "pthread_create consumer");
    
    //回收线程
    pthread_join(ptid, NULL);
    pthread_join(ctid, NULL);

    //销毁信号量
    sem_destroy(&remain);
    sem_destroy(&product);

    return 0;

}